package com.gobang.service.impl;

import com.gobang.common.exception.ErrorCode;
import com.gobang.common.util.MessageUtils;
import com.gobang.domain.dto.*;
import com.gobang.domain.message.*;
import com.gobang.domain.vo.UserInfoVO;
import com.gobang.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.Set;

/**
 * 实时消息服务实现类
 * 职责：WebSocket消息推送和转发，不处理任何业务逻辑
 * 
 * @author System
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class MessageServiceImpl implements MessageService {

    // 用来发送WS消息的类
    private final SimpMessagingTemplate messagingTemplate;
    private final ConnectionManagerService connectionManagerService;
    // private final GameService gameService;
    private final NewGameService gameService;
    private final UserService userService;

    // ========== 消息推送功能（核心职责） ==========
    
    @Override
    public void sendToUser(Long userId, WebSocketMessage message) {
        try {
            if (!connectionManagerService.isUserOnline(userId)) {
                log.warn("用户不在线，无法发送消息：userId={}", userId);
                return;
            }
            
            // 使用STOMP的用户目标发送消息
            messagingTemplate.convertAndSendToUser(
                userId.toString(), 
                "/queue/messages", 
                message
            );
            
            log.debug("消息发送成功：userId={}, messageType={}", userId, message.getType());
        } catch (Exception e) {
            log.error("消息发送失败：userId={}, messageType={}", userId, message.getType(), e);
        }
    }
    
    @Override
    public void broadcastToRoom(String roomId, WebSocketMessage message) {
        try {
            Set<Long> roomUsers = connectionManagerService.getRoomUsers(roomId);
            if (roomUsers.isEmpty()) {
                log.warn("房间无在线用户，无法广播消息：roomId={}", roomId);
                return;
            }
            
            // 向房间内所有用户发送消息
            for (Long userId : roomUsers) {
                sendToUser(userId, message);
            }
            
            log.debug("房间广播消息成功：roomId={}, userCount={}, messageType={}", 
                     roomId, roomUsers.size(), message.getType());
        } catch (Exception e) {
            log.error("房间广播消息失败：roomId={}, messageType={}", roomId, message.getType(), e);
        }
    }
    
    @Override
    public void sendMatchStatusUpdate(Long userId, MatchStatusUpdateMessage message) {
        sendToUser(userId, message);
    }
    
    @Override
    public void sendGameStateUpdate(String roomId, GameStateUpdateMessage message) {
        broadcastToRoom(roomId, message);
    }
    
    @Override
    public void sendGameOverNotification(String roomId, GameOverMessage message) {
        broadcastToRoom(roomId, message);
    }
    
    @Override
    public void sendMatchSuccessNotification(Long userId, MatchSuccessMessage message) {
        sendToUser(userId, message);
    }
    
    @Override
    public void sendOpponentOfflineNotification(String roomId, OpponentOfflineMessage message) {
        broadcastToRoom(roomId, message);
    }
    
    @Override
    public void sendHeartbeat(Long userId) {
        HeartbeatMessage heartbeat = MessageUtils.createHeartbeatMessage();
        sendToUser(userId, heartbeat);
    }
    
    @Override
    public void sendErrorResponse(Long userId, ErrorCode errorCode, String message) {
        ErrorResponseMessage errorMessage = MessageUtils.createErrorMessage(errorCode, message);
        sendToUser(userId, errorMessage);
    }
    
    // ========== 消息转发功能（不处理业务逻辑，仅转发） ==========
    
    @Override
    public void forwardMoveRequest(Long userId, MoveRequestMessage message) {
        try {
            log.info("转发落子请求：用户{}，房间{}，位置({},{})", 
                    userId, message.getData().getRoomId(), message.getData().getRow(), message.getData().getCol());
            
            // 转发给游戏核心模块处理
//            GameService.MoveResult result = gameService.processMove(
//                userId, message.getRoomId(), message.getRow(), message.getCol()
//            );
            MoveResponseDTO result = gameService.makeMove(
                    message.getData().getRoomId(), userId, message.getData().getRow(), message.getData().getCol());

            // 构造响应消息并推送
            MoveResponseMessage response;
            if (result.getSuccess()) {
                response = MessageUtils.createSuccessMoveResponse(
                    result.getRoomId(),
                    result.getMove().getRow(),
                    result.getMove().getCol(),
                    result.getMove().getColor(),
                    result.getGameStatus(),
                    result.getNextTurn(),
                    result.getIsGameOver(),
                    result.getWinnerId()
                );
                
                // 广播给房间内所有用户
                broadcastToRoom(message.getData().getRoomId(), response);

                // 如果游戏结束，发送游戏结束WS通知
                if (result.getIsGameOver()) {
                    // gameService.handleGameOver(message.getRoomId(), result.getWinnerId());
                    UserInfoVO user = userService.getUserById(result.getWinnerId());
                    GameOverMessage gameOverMsg = MessageUtils.createGameOverMessage(
                            result.getRoomId(),
                            result.getWinnerId(),
                            user.getUsername(),
                            "WIN",
                            5,
                            user.getCurrentScore(),
                            "FIVE_IN_ROW"
                    );
                    sendGameOverNotification(message.getData().getRoomId(), gameOverMsg);
                }

//                // 如果游戏结束，广播游戏结束消息
//                if (result.isGameOver()) {
//                    GameOverMessage gameOverMsg = MessageUtils.createGameOverMessage(
//                        result.getRoomId(),
//                        result.getWinnerId(),
//                        "玩家" + result.getWinnerId(), // TODO: 从用户服务获取用户名
//                        "WIN",
//                        5, // TODO: 从积分服务获取积分变化
//                        2000, // TODO: 从用户服务获取新积分
//                        "FIVE_IN_ROW"
//                    );
//                    broadcastToRoom(message.getRoomId(), gameOverMsg);
//                }
            } else {
                response = MessageUtils.createFailedMoveResponse(
                    result.getRoomId(),
                    ErrorCode.GAME_MOVE_INVALID.getCode(),
                    result.getErrorMessage(),
                    result.getNextTurn()
                );
                
                // 只发送给请求用户
                sendToUser(userId, response);
            }
            
        } catch (Exception e) {
            log.error("转发落子请求异常：userId={}, roomId={}", userId, message.getData().getRoomId(), e);
            sendErrorResponse(userId, ErrorCode.GAME_MOVE_INVALID, "落子处理失败");
        }
    }
    
    @Override
    public void forwardGameStateRequest(Long userId, String roomId) {
        try {
            log.info("转发游戏状态请求：用户{}，房间{}", userId, roomId);
            
            // 转发给游戏核心模块查询
            GameStateUpdateMessage stateMessage = gameService.getGameState(roomId, userId);

            // 推送查询结果
            sendToUser(userId, stateMessage);

        } catch (Exception e) {
            log.error("转发游戏状态请求异常：userId={}, roomId={}", userId, roomId, e);
            sendErrorResponse(userId, ErrorCode.GAME_ROOM_NOT_FOUND, "获取游戏状态失败");
        }
    }
    
//    @Override
//    public void forwardMatchRequest(Long userId) {
//        try {
//            log.info("转发匹配请求：用户{}", userId);
//
//            // 更新用户状态为匹配中
//            connectionManagerService.updateUserStatus(userId, "matching");
//
//            // 转发给匹配系统模块处理
//            MatchService.MatchResult result = matchService.processMatchRequest(userId);
//
//            if (result.isSuccess()) {
//                if ("MATCHING".equals(result.getStatus())) {
//                    // 发送匹配状态更新
//                    MatchStatusUpdateMessage statusMsg = MessageUtils.createMatchStatusUpdateMessage(
//                        result.getStatus(),
//                        result.getWaitTime(),
//                        result.getQueuePosition()
//                    );
//                    sendToUser(userId, statusMsg);
//                } else if ("MATCH_SUCCESS".equals(result.getStatus())) {
//                    // 发送匹配成功通知
//                    MatchSuccessMessage.MatchSuccessData data = MatchSuccessMessage.MatchSuccessData.builder()
//                            .roomId(result.getRoomId())
//                            .opponent(MatchSuccessMessage.OpponentInfo.builder()
//                                    .id(result.getOpponent().getId())
//                                    .username(result.getOpponent().getUsername())
//                                    .currentScore(result.getOpponent().getCurrentScore())
//                                    .build())
//                            .playerColor(result.getPlayerColor())
//                            .startTime(result.getStartTime())
//                            .build();
//
//                    MatchSuccessMessage successMsg = new MatchSuccessMessage(data);
//                    sendToUser(userId, successMsg);
//
//                    // 更新用户状态为游戏中，并加入房间
//                    connectionManagerService.updateUserStatus(userId, "gaming");
//                    connectionManagerService.addUserToRoom(result.getRoomId(), userId);
//                    connectionManagerService.addUserToRoom(result.getRoomId(), result.getOpponent().getId());
//                }
//            } else {
//                sendErrorResponse(userId, ErrorCode.MATCH_REQUEST_FAILED, result.getErrorMessage());
//            }
//
//        } catch (Exception e) {
//            log.error("转发匹配请求异常：userId={}", userId, e);
//            sendErrorResponse(userId, ErrorCode.MATCH_REQUEST_FAILED, "匹配请求失败");
//        }
//    }
//
//    @Override
//    public void forwardCancelMatchRequest(Long userId) {
//        try {
//            log.info("转发取消匹配请求：用户{}", userId);
//
//            // 转发给匹配系统模块处理
//            MatchService.CancelMatchResult result = matchService.processCancelMatchRequest(userId);
//
//            if (result.isSuccess()) {
//                // 更新用户状态为在线
//                connectionManagerService.updateUserStatus(userId, "online");
//
//                // 发送取消成功的匹配状态更新
//                MatchStatusUpdateMessage statusMsg = MessageUtils.createMatchStatusUpdateMessage(
//                    "ONLINE", 0, 0
//                );
//                sendToUser(userId, statusMsg);
//            } else {
//                sendErrorResponse(userId, ErrorCode.MATCH_CANCEL_FAILED, result.getErrorMessage());
//            }
//
//        } catch (Exception e) {
//            log.error("转发取消匹配请求异常：userId={}", userId, e);
//            sendErrorResponse(userId, ErrorCode.MATCH_CANCEL_FAILED, "取消匹配失败");
//        }
//    }
}